package com.wisdom.client.processor;


import com.wisdom.core.annotation.WisdomRpcRemote;
import com.wisdom.core.exception.RpcException;
import com.wisdom.core.factory.SpringBeanFactory;
import com.wisdom.core.proxy.ProxyFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * @description: <handle rpc request info and send rpc request>
 * @author: Leo
 * @date: 2021-08-23 17:44
 */
@Component
@Slf4j
public class RpcRequestProcessor implements BeanPostProcessor, ApplicationContextAware {

    private ProxyFactory proxyFactory;

    /**
     * Bean的后置处理器   针对Bean中标注了 WisdomRpcRemote 的属性生成代理
     *
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        //1. 获取Bean的属性
        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                WisdomRpcRemote wisdomRpcRemote = field.getAnnotation(WisdomRpcRemote.class);
                if (wisdomRpcRemote != null) {
                    Object proxy = proxyFactory.newProxyInstance(field.getType());
                    log.info("为{}生成代理", field.getClass().getName());
                    if (proxy != null) {
                        field.set(bean, proxy);
                    }

                }
            } catch (Exception e) {
                log.info("RpcRequestProcessor 生成代理失败，msg 是 {}", e.getMessage());
                throw new RpcException(e.getMessage(), e);
            }
        }
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        proxyFactory = applicationContext.getBean(ProxyFactory.class);
    }
}
